package top.yxf.mapstruct.conversion;


import org.mapstruct.*;
import org.mapstruct.factory.Mappers;
import top.yxf.mapstruct.dto.CarDto;
import top.yxf.mapstruct.dto.HobbyDto;
import top.yxf.mapstruct.dto.UserDto;
import top.yxf.mapstruct.vo.CarVo;
import top.yxf.mapstruct.vo.HobbyVo;
import top.yxf.mapstruct.vo.ResVo;
import top.yxf.mapstruct.vo.UserVo;

import java.util.List;

/**
 * @author zw
 */
@Mapper(componentModel = "spring")
public abstract class UserConversion {

    public static UserConversion INSTANCE = Mappers.getMapper(UserConversion.class);


    @Mappings(value = {
            @Mapping(source = "userId", target = "userId"),
            @Mapping(source = "gender", target = "sex"),
            @Mapping(source = "birth", target = "birth", dateFormat = "yyyy-MM-dd HH:mm:ss"),
            @Mapping(source = "carDto", target = "carVo")
    })
    public abstract UserVo dto2Vo(UserDto userDto);

    /**
     * numberFormat注意事项：是String转Number或Number或String才有效，
     * 如果是Number转Number或其他类型的转换均不生效，比如Double转Double（用于格式化小数位）时不生效。
     * @param carDto
     * @return
     */
    @Mappings(
            value = {
                    @Mapping(target = "name", source = "carName"),
                    @Mapping(target = "id", source = "carId"),
                    @Mapping(target = "color", source = "color", ignore = true),
                    @Mapping(target = "price", source = "price"),
                    @Mapping(target = "totalPrice", source = "totalPrice", numberFormat = "#.0"),
            }
    )
    public abstract CarVo carDto2Vo(CarDto carDto);

    /**
     * @AfterMapping 表示在mapstruct转换后调用该方法
     * @MappingTarget 表示传来的userVo 已经是赋值过的
     * @param userDto
     * @param userVo
     */
    @AfterMapping
    public void dto2voAfter(UserDto userDto, @MappingTarget UserVo userVo) {
        userVo.setHasHobby((null != userDto.getHobbyDtoList() && !userDto.getHobbyDtoList().isEmpty()));
    }


    /**
     * dto2Vo 方法的列表转换
     * 注意：某个对象列表转换必须有该对象的转换才能转换
     * @param userDto
     * @return
     */
    public abstract List<UserVo> dtos2Vos(List<UserDto> userDto);


    /**
     * @BeanMapping 忽略mapstruct的默认映射行为，避免不需要的赋值，避免属性覆盖
     * @param userDto
     * @return
     */
    @BeanMapping(ignoreByDefault = true)
    @Mappings(value = {
            @Mapping(source = "userId", target = "userId"),
            @Mapping(source = "userName", target = "userName"),
    })
    public abstract ResVo userDto2Resvo(UserDto userDto);

    /**
     * @InheritConfiguration 继承配置
     * @param userDto
     * @return
     */
    @InheritConfiguration
    @Mapping(source = "userId", target = "userId", ignore = true)
    public abstract void updateResVo(UserDto userDto, @MappingTarget ResVo resVo);


    /**
     * @InheritInverseConfiguration 反向继承配置 只继承@Mapping配置 不会继承@BeanMapping配置
     * name： 指定继承哪个配置的方法名
     * @param resVo
     * @return
     */
    @InheritInverseConfiguration(name = "userDto2Resvo")
    public abstract UserDto resvo2UserDto(ResVo resVo);
}
